package cn.ava.ymcc.mq.listener;

import cn.ava.ymcc.domain.CourseOrder;
import cn.ava.ymcc.dto.Order2PayDto;
import cn.ava.ymcc.service.ICourseOrderService;
import com.alibaba.fastjson.JSONObject;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;

import java.nio.charset.StandardCharsets;


@RocketMQTransactionListener(txProducerGroup = "tx-order2Pay-group")
public class Order2PayTransMsgListener implements RocketMQLocalTransactionListener{

    @Autowired
    private ICourseOrderService courseOrderService;


    /**
     * 使用MQ最终一致性执行本地事务同时保存订单与支付单
     * @param msg
     * @param arg
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        // 非空校验
        if (arg == null) {
            return RocketMQLocalTransactionState.ROLLBACK; // 数据为空直接失败回滚
        }
        // 保存订单
        try {
            CourseOrder order = (CourseOrder)arg;
            courseOrderService.saveAndItem(order);
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            e.printStackTrace();
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        byte[] payload = (byte[]) msg.getPayload();
        String jsonObj = new String(payload, StandardCharsets.UTF_8);
        try {
            // 转为对象
            Order2PayDto order2PayDto = JSONObject.parseObject(jsonObj, Order2PayDto.class);
            // 校验本地事务是否执行成功,订单是否保存
            CourseOrder courseOrder = courseOrderService.checkOrder(order2PayDto.getOrderNo());
            if (courseOrder == null) {
                return RocketMQLocalTransactionState.ROLLBACK;
            }
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            e.printStackTrace();
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}
